/**
 *	4.编写一组函数，实现位数组，函数的原型如下：
 *	void set_bit(char bit_array[], unsigned bit_number);
 *
 *	void clear_bit(char bit_array[], unsigned bit_number);
 *
 *	void assign_bit(char bit_array[], unsigned bit_number, int value);
 *
 *	int test_bit(char bit_arrar[], unsigned bit_number);
 *	每个函数的第一个参数是字符数组，用于实际储存所有的位，第二个参数用于标识需要访问的位。
 *	函数的调用者必须确保这个值不要太大，以至于超出数组边界。第一个函数把指定的位设置为1,第二个函数把指定的位清零，
 *	如果value的值为1,第三个函数就把指定的位清零，否则置一，至于最后一个函数，如果参数中指定的位不为零就返回真，
 *	否则返回假。
**/

#include <stdio.h>
#include <limits.h>

void set_bit(char bit_array[], unsigned bit_number);
void clear_bit(char bit_array[], unsigned bit_number);
void assign_bit(char bit_array[], unsigned bit_number, int value);
int test_bit(char bit_array[], unsigned bit_number);

int main()
{
	char num[10] = {0};	

	set_bit(num, 0);
	printf("%d\n", num[0]);
	clear_bit(num, 0);
	printf("%d\n", num[0]);
	assign_bit(num, 8, 1);
	printf("%d\n", num[1]);
	assign_bit(num, 8, 0);
	printf("test = %d\n", test_bit(num, 8));

	return 0;
}

unsigned character_offset(unsigned bit_number)
{
	return bit_number / CHAR_BIT;
}

unsigned bit_offset(unsigned bit_number)
{
	return bit_number % CHAR_BIT;
}

void set_bit(char bit_array[], unsigned bit_number)
{
	bit_array[character_offset(bit_number)] |= 1 << bit_offset(bit_number);
}

void clear_bit(char bit_array[], unsigned bit_number)
{
	bit_array[character_offset(bit_number)] &= ~(1 << bit_offset(bit_number));
}

void assign_bit(char bit_array[], unsigned bit_number, int value)
{
	if(!value)
		clear_bit(bit_array, bit_number);
	else
		set_bit(bit_array, bit_number);
}

int test_bit(char bit_array[], unsigned bit_number)
{
	if(!(bit_array[character_offset(bit_number)] & (1 << bit_offset(bit_number))))
		return 0;
	else
		return 1;
}

/*刚开始看我是不太懂的，咋整得这么麻烦呢，接下来分析一下：*/
/*
首先bit_array是一个字符数组，它里面存的是字符，假定在你的机器上每个字符的二进制位数为n，那么bit_array的每一个元素都有n位，如果bit_array有m个元素，那么总的bit_array就有m * n个位，如果指定在bit_number位的话，那么应该就是数组的第bit_number / n 个元素，所以character_offset函数的作用就是将bit_number 转换为字符数组中的元素
因为每一个元素都只有n位，而bit_number这个值是针对所有的元素位数的，所以你需要将它定位在第bit_number这个元素的位数，而这个位可以用取余的方法bit_number % n来得到，所以bit_offset的作用就是把bit_number转换到需要改变的元素的精确位
而CHAR_BIT就是机器上字符的二进制位数
*/
